import 'package:flutter/services.dart';
import 'package:tencent_rtc/trtc_cloud_def.dart';

import 'package:tencent_rtc/trtc_cloud_listener.dart';

import 'package:tencent_rtc/tx_audio_effect_manager.dart';

import 'package:tencent_rtc/tx_device_manager.dart';

import '../trtc_cloud.dart';
import 'tx_device_manager_ohos_impl.dart';

class TRTCCloudOhosImpl extends TRTCCloud {

  static TRTCCloud? _instance;
  static TRTCCloud getInstance() {
    _instance ??= TRTCCloudOhosImpl._();
    return _instance!;
  }

  final MethodChannel _channel = const MethodChannel('TencentRTCffi');
  final List<TRTCCloudListener> _listeners = [];

  TRTCCloudOhosImpl._() {
    _channel.setMethodCallHandler((MethodCall call) async {
      print("TRTCCloud: ${call.method}");
      switch (call.method) {
        case 'onError':
          {
            int code = call.arguments['code'];
            String msg = call.arguments['message'];
            for (var listener in _listeners) {
              listener.onError?.call(code, msg);
            }
          }
          break;
        case 'onWarning':
          {
            int code = call.arguments['code'];
            String msg = call.arguments['message'];
            for (var listener in _listeners) {
              listener.onWarning?.call(code, msg);
            }
          }
          break;
        case "onEnterRoom":
          for (var listener in _listeners) {
            listener.onEnterRoom?.call(call.arguments);
          }
          break;
        case "onExitRoom":
          for (var listener in _listeners) {
            listener.onExitRoom?.call(call.arguments);
          }
          break;
        case "onRemoteUserEnterRoom":
          for (var listener in _listeners) {
            listener.onRemoteUserEnterRoom?.call(call.arguments);
          }
          break;
        case "onRemoteUserLeaveRoom": {
          String userId = call.arguments['userId'];
          int reason = call.arguments['reason'];
          for (var listener in _listeners) {
            listener.onRemoteUserLeaveRoom?.call(userId, reason);
          }
        }break;
        case "onUserVideoAvailable":{
          String userId = call.arguments['userId'];
          bool available = call.arguments['available'];
          for (var listener in _listeners) {
            listener.onUserVideoAvailable?.call(userId, available);
          }
        }break;
        case "onUserSubStreamAvailable":{
          String userId = call.arguments['userId'];
          bool available = call.arguments['available'];
          for (var listener in _listeners) {
            listener.onUserSubStreamAvailable?.call(userId, available);
          }
        }break;
        case "onUserAudioAvailable":{
          String userId = call.arguments['userId'];
          bool available = call.arguments['available'];
          for (var listener in _listeners) {
            listener.onUserAudioAvailable?.call(userId, available);
          }
        }break;
      }
    });
  }

  Future<void> initEngine() {
    return  _channel.invokeMethod('initialize');
  }

  Future destroyEngine() {
    return  _channel.invokeMethod('destroy');
  }

  @override
  void registerListener(TRTCCloudListener func) {
    _listeners.add(func);
  }

  @override
  void unRegisterListener(TRTCCloudListener func) {
    _listeners.remove(func);
  }

  @override
  void enterRoom(TRTCParams param, TRTCAppScene scene) {
    _channel.invokeMethod('enterRoom', {
      'sdkAppId': param.sdkAppId,
      'userId': param.userId,
      'userSig': param.userSig,
      'roomId': param.roomId,
      'strRoomId': param.strRoomId,
      'streamId': param.streamId,
      'userDefineRecordId': param.userDefineRecordId,
      'privateMapKey': param.privateMapKey,
      'businessInfo': param.businessInfo,
      'role': param.role.index,
      'scene': scene.index,
    });
  }
  @override
  void exitRoom() {
    _channel.invokeMethod('exitRoom');
  }

  @override
  void startLocalAudio(TRTCAudioQuality quality) {
    _channel.invokeMethod('startLocalAudio', quality.index);
  }

  @override
  void stopLocalAudio(){
    _channel.invokeMethod('stopLocalAudio');
  }

  @override
  void muteLocalVideo(TRTCVideoStreamType streamType, bool mute){
    _channel.invokeMethod('muteLocalVideo', {
      'streamType': streamType.index,
      'mute': mute,
    });
  }

  @override
  void stopRemoteView(String userId, TRTCVideoStreamType streamType) {
    _channel.invokeMethod('stopRemoteView', {
      'userId': userId,
      'streamType': streamType.index,
    });
  }

  @override
  void startScreenCapture(int viewId, TRTCVideoStreamType streamType, TRTCVideoEncParam encParam){
    // _channel.invokeMethod('startScreenCapture', {
    //   'viewId': viewId,
    //   'streamType': streamType.index,
    //   'videoBitrate': encParam.videoBitrate,
    //   'videoFps': encParam.videoFps,
    //   'minVideoBitrate': encParam.minVideoBitrate,
    //   'enableAdjustRes': encParam.enableAdjustRes,
    //   'videoResolution': encParam.videoResolution.index,
    //   'videoResolutionMode': encParam.videoResolutionMode.index,
    // });
  }

  @override
  void stopScreenCapture(){
    // _channel.invokeMethod('stopScreenCapture');
  }

  @override
  TRTCScreenCaptureSourceList? getScreenCaptureSources(TRTCSize thumbnail, TRTCSize icon){
    return null;
  }

  @override
  void selectScreenCaptureTarget(TRTCScreenCaptureSourceInfo source, TRTCRect rect, TRTCScreenCaptureProperty property){
    // _channel.invokeMethod('selectScreenCaptureTarget', {
    //   'source': source.toJson(),
    //   'rect': rect.toJson(),
    //   'property': property.toJson(),
    // });
  }

  @override
  void startLocalPreview(bool frontCamera, int viewId){
    _channel.invokeMethod('startLocalPreview', {
      'frontCamera': frontCamera,
      'viewId': viewId,
    });
  }

  @override
  void startRemoteView(String userId, TRTCVideoStreamType streamType, int viewId){
    _channel.invokeMethod('startRemoteView', {
      'userId': userId,
      'streamType': streamType.index,
      'viewId': viewId,
    });
  }

  @override
  TXDeviceManager getDeviceManager() {
    return TXDeviceManagerOhosImpl(_channel);
  }

  @override
  String callExperimentalAPI(String jsonStr) {
    // TODO: implement callExperimentalAPI
    throw UnimplementedError();
  }

  @override
  void connectOtherRoom(String param) {
    // TODO: implement connectOtherRoom
  }

  @override
  void disconnectOtherRoom() {
    // TODO: implement disconnectOtherRoom
  }

  @override
  void enableAudioVolumeEvaluation(bool enable, TRTCAudioVolumeEvaluateParams params) {
    // TODO: implement enableAudioVolumeEvaluation
  }

  @override
  void enableCustomAudioCapture(bool enable) {
    // TODO: implement enableCustomAudioCapture
  }

  @override
  void enableCustomVideoCapture(TRTCVideoStreamType streamType, bool enable) {
    // TODO: implement enableCustomVideoCapture
  }

  @override
  void enableMixExternalAudioFrame(bool enablePublish, bool enablePlayout) {
    // TODO: implement enableMixExternalAudioFrame
  }

  @override
  int enableSmallVideoStream(bool enable, TRTCVideoEncParam smallVideoEncParam) {
    // TODO: implement enableSmallVideoStream
    throw UnimplementedError();
  }


  @override
  int getAudioCaptureVolume() {
    // TODO: implement getAudioCaptureVolume
    throw UnimplementedError();
  }

  @override
  TXAudioEffectManager getAudioEffectManager() {
    // TODO: implement getAudioEffectManager
    throw UnimplementedError();
  }

  @override
  int getAudioPlayoutVolume() {
    // TODO: implement getAudioPlayoutVolume
    throw UnimplementedError();
  }


  @override
  String getSDKVersion() {
    // TODO: implement getSDKVersion
    throw UnimplementedError();
  }

  @override
  void muteAllRemoteAudio(bool mute) {
    // TODO: implement muteAllRemoteAudio
  }

  @override
  void muteAllRemoteVideoStreams(bool mute) {
    // TODO: implement muteAllRemoteVideoStreams
  }

  @override
  void muteLocalAudio(bool mute) {
    // TODO: implement muteLocalAudio
  }

  @override
  void muteRemoteAudio(String userId, bool mute) {
    // TODO: implement muteRemoteAudio
  }

  @override
  void muteRemoteVideoStream(String userId, TRTCVideoStreamType streamType, bool mute) {
    // TODO: implement muteRemoteVideoStream
  }

  @override
  void pauseScreenCapture() {
    // TODO: implement pauseScreenCapture
  }



  @override
  void resumeScreenCapture() {
    // TODO: implement resumeScreenCapture
  }

  @override
  void sendCustomAudioData(TRTCAudioFrame frame) {
    // TODO: implement sendCustomAudioData
  }

  @override
  bool sendCustomCmdMsg(int cmdID, String data, bool reliable, bool ordered) {
    // TODO: implement sendCustomCmdMsg
    throw UnimplementedError();
  }

  @override
  void sendCustomVideoData(TRTCVideoStreamType streamType, TRTCVideoFrame frame) {
    // TODO: implement sendCustomVideoData
  }

  @override
  bool sendSEIMsg(String data, int repeatCount) {
    // TODO: implement sendSEIMsg
    throw UnimplementedError();
  }

  @override
  void setAudioCaptureVolume(int volume) {
    // TODO: implement setAudioCaptureVolume
  }

  @override
  void setAudioPlayoutVolume(int volume) {
    // TODO: implement setAudioPlayoutVolume
  }

  @override
  void setBeautyStyle(TRTCBeautyStyle style, int beautyLevel, int whitenessLevel, int ruddinessLevel) {
    // TODO: implement setBeautyStyle
  }

  @override
  void setConsoleEnabled(bool enabled) {
    // TODO: implement setConsoleEnabled
  }

  @override
  void setDefaultStreamRecvMode(bool autoRecvAudio, bool autoRecvVideo) {
    // TODO: implement setDefaultStreamRecvMode
  }

  @override
  void setGravitySensorAdaptiveMode(TRTCGSensorMode mode) {
    // TODO: implement setGravitySensorAdaptiveMode
  }

  @override
  void setLocalRenderParams(TRTCRenderParams params) {
    // TODO: implement setLocalRenderParams
  }

  @override
  void setLogCallback(TRTCLogCallback? callback) {
    // TODO: implement setLogCallback
  }

  @override
  void setLogCompressEnabled(bool enabled) {
    // TODO: implement setLogCompressEnabled
  }

  @override
  void setLogDirPath(String path) {
    // TODO: implement setLogDirPath
  }

  @override
  void setLogLevel(TRTCLogLevel level) {
    // TODO: implement setLogLevel
  }

  @override
  void setNetworkQosParam(TRTCNetworkQosParam params) {
    // TODO: implement setNetworkQosParam
  }

  @override
  void setRemoteAudioVolume(String userId, int volume) {
    // TODO: implement setRemoteAudioVolume
  }

  @override
  void setRemoteRenderParams(String userId, TRTCVideoStreamType streamType, TRTCRenderParams params) {
    // TODO: implement setRemoteRenderParams
  }

  @override
  void setRemoteVideoStreamType(String userId, TRTCVideoStreamType streamType) {
    // TODO: implement setRemoteVideoStreamType
  }

  @override
  void setSubStreamEncoderParam(TRTCVideoEncParam param) {
    // TODO: implement setSubStreamEncoderParam
  }

  @override
  void setSystemAudioLoopbackVolume(int volume) {
    // TODO: implement setSystemAudioLoopbackVolume
  }

  @override
  void setVideoEncoderParam(TRTCVideoEncParam params) {
    // TODO: implement setVideoEncoderParam
  }

  @override
  void setVideoMuteImage(String imagePath, int fps) {
    // TODO: implement setVideoMuteImage
  }

  @override
  void setWatermark(String imagePath, TRTCVideoStreamType streamType, double x, double y, double width) {
    // TODO: implement setWatermark
  }

  @override
  void showDebugView(int showType) {
    // TODO: implement showDebugView
  }

  @override
  void snapshotVideo(String userId, TRTCVideoStreamType streamType, TRTCSnapshotSourceType sourceType, {String? path}) {
    // TODO: implement snapshotVideo
  }

  @override
  int startLocalRecording(TRTCLocalRecordingParams param) {
    // TODO: implement startLocalRecording
    throw UnimplementedError();
  }

  @override
  void startPublishMediaStream(TRTCPublishTarget target, TRTCStreamEncoderParam param, TRTCStreamMixingConfig config) {
    // TODO: implement startPublishMediaStream
  }

  @override
  void startScreenCaptureByReplaykit(TRTCVideoStreamType streamType, TRTCVideoEncParam encParam, String? appGroup) {
    // TODO: implement startScreenCaptureByReplaykit
  }

  @override
  int startSpeedTest(TRTCSpeedTestParams params) {
    // TODO: implement startSpeedTest
    throw UnimplementedError();
  }

  @override
  void startSystemAudioLoopback({String? deviceName}) {
    // TODO: implement startSystemAudioLoopback
  }

  @override
  void stopAllRemoteView() {
    // TODO: implement stopAllRemoteView
  }

  @override
  void stopLocalPreview() {
    // TODO: implement stopLocalPreview
  }

  @override
  void stopLocalRecording() {
    // TODO: implement stopLocalRecording
  }

  @override
  void stopPublishMediaStream(String taskId) {
    // TODO: implement stopPublishMediaStream
  }

  @override
  void stopSpeedTest() {
    // TODO: implement stopSpeedTest
  }

  @override
  void stopSystemAudioLoopback() {
    // TODO: implement stopSystemAudioLoopback
  }

  @override
  void switchRole(TRTCRoleType role) {
    // TODO: implement switchRole
  }

  @override
  void switchRoom(TRTCSwitchRoomConfig config) {
    // TODO: implement switchRoom
  }


  @override
  void updateLocalView(int viewId) {
    // TODO: implement updateLocalView
  }

  @override
  void updatePublishMediaStream(String taskId, TRTCPublishTarget target, TRTCStreamEncoderParam param, TRTCStreamMixingConfig config) {
    // TODO: implement updatePublishMediaStream
  }

  @override
  void updateRemoteView(String userId, TRTCVideoStreamType streamType, int viewId) {
    // TODO: implement updateRemoteView
  }

}